package com.zhouqinuan.spring.cloud.develop.framework.routing.datasource.config;

import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.zaxxer.hikari.HikariDataSource;
import com.zhouqinuan.spring.cloud.develop.framework.routing.datasource.RoutingDataSource;
import com.zhouqinuan.spring.cloud.develop.framework.routing.datasource.RoutingDataSourceProperties;
import com.zhouqinuan.spring.cloud.develop.framework.routing.datasource.RoutingDataSourceProperties.DataSourceProperties;
import com.zhouqinuan.spring.cloud.develop.framework.routing.datasource.aop.RoutingDataSourceAop;

@Configuration
@EnableConfigurationProperties({ RoutingDataSourceProperties.class })
public class RoutingDataSourceConfiguration {

    @Autowired
    private RoutingDataSourceProperties routingDataSourceProperties;

    @Bean
    public DataSource routingDataSource() throws Exception {
        RoutingDataSource routingDataSource = new RoutingDataSource();

        Map<Object, Object> dataSourceMap = new HashMap<>();
        for (DataSourceProperties properties : routingDataSourceProperties.getList()) {
            HikariDataSource dataSource = new HikariDataSource();
            dataSource.setJdbcUrl(properties.getUrl());
            dataSource.setUsername(properties.getUsername());
            dataSource.setPassword(properties.getPassword());
            dataSource.setDriverClassName(properties.getDriverClassName());
            dataSource.setMinimumIdle(properties.getMinimumIdle());
            dataSource.setIdleTimeout(properties.getIdleTimeout());
            dataSource.setMaximumPoolSize(properties.getMaximumPoolSize());
            dataSource.setAutoCommit(properties.isAutoCommit());
            dataSource.setPoolName(properties.getPoolName());
            dataSource.setMaxLifetime(properties.getMaxLifetime());
            dataSource.setConnectionTimeout(properties.getConnectionTimeout());
            dataSource.setConnectionTestQuery(properties.getConnectionTestQuery());

            dataSourceMap.put(properties.getPoolName(), dataSource);

            if (properties.isDefaultDb()) {
                routingDataSource.setDefaultTargetDataSource(dataSource);
            }
        }

        routingDataSource.setTargetDataSources(dataSourceMap);

        return routingDataSource;
    }

    @Bean
    public RoutingDataSourceAop routingDataSourceAop() {

        return new RoutingDataSourceAop();
    }
}
